package com.xdy.secret.algorithm;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @Author: XDY.
 * @Email: 2280944114@qq.com
 * @CreateTime: 2023-09-05  21:37
 * @Description: 对称加密算法 AES DES
 * @Version: 1.0
 */
public class DesAesDemo {
    public static void main(String[] args) {
        //原文
        String input = "许琳康";
        //定义key(密钥) DES密钥key必须是8个字节
        String desKey = "12345678";
        //AES密钥key必须是16个字节
        String aesKey = "1234567812345678";
        //使用的加密算法
        //DES加密算法，ECB加密模式，PKCS5Padding填充模式
        //ECB Electronic codebook, 电子密码本. 需要加密的消息按照块密码的块大小被分为数个块，并对每个块进行独立加密
//        String transformation = "DES";//DES 相当于默认是DES/ECB/PKCS5Padding
        //CBC加密模式需要一个IV向量，不同的向量加密的密文不同
        //CBC Cipher-block chaining, 密码块链接. 每个明文块先与前一个密文块进行异或后，再进行加密。在这种方法中，每个密文块都依赖于它前面的所有明文块
        //PKCS5Padding 数据块的大小为8位, 不够就补足
        String transformation = "DES/CBC/PKCS5Padding";
        IvParameterSpec iv = new IvParameterSpec(desKey.getBytes());
        //加密类型
        String algorithm = "DES";
        //使用的加密算法
//        String transformation2 = "AES";//AES 相当于默认是AES/ECB/PKCS5Padding
        String transformation2 = "AES/CBC/PKCS5Padding";//AES 相当于默认是AES/ECB/PKCS5Padding
        IvParameterSpec iv2 = new IvParameterSpec(aesKey.getBytes());
        //加密类型
        String algorithm2 = "AES";
        try {
            //创建加密对象
            Cipher cipher = Cipher.getInstance(transformation);
            Cipher cipher2 = Cipher.getInstance(transformation2);
            //创建加密规则
            SecretKeySpec secretKeySpec = new SecretKeySpec(desKey.getBytes(), algorithm);
            SecretKeySpec secretKeySpec2 = new SecretKeySpec(aesKey.getBytes(), algorithm2);
            //ENCRYPT_MODE加密模式，DECRYPT_MODE解密模式
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,iv);
            cipher2.init(Cipher.ENCRYPT_MODE,secretKeySpec2,iv2);
            //调用加密方法
            byte[] decryptData = cipher.doFinal(input.getBytes());
            byte[] decryptData2 = cipher2.doFinal(input.getBytes());
            String encode = Base64.encode(decryptData);
            String encode2 = Base64.encode(decryptData2);
            System.out.println("DES加密："+encode);
            System.out.println("DES解密："+decryptDES(encode,desKey,transformation,algorithm));
            System.out.println("AES加密："+encode2);
            System.out.println("AES解密："+decryptDES(encode2,aesKey,transformation2,algorithm2));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @param encryptDES 密文
     * @param key 密钥
     * @param transformation 加密算法
     * @param algorithm 加密类型
     * @return
     */
    public static String decryptDES(String encryptDES,String key,String transformation,String algorithm){
        try {
            Cipher cipher = Cipher.getInstance(transformation);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), algorithm);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes());
            cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,iv);
            byte[] bytes = cipher.doFinal(Base64.decode(encryptDES));
            return new String(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
